#include <stdio.h>
#include <string.h>

static void xy_close_g_all(void)
{
	int i;
	char * cfgmsg[][1] = {
		{"$$cfgmsg,0,0,0\r\n"},
		{"$$cfgmsg,0,1,0\r\n"},
		{"$$cfgmsg,0,2,0\r\n"},
		{"$$cfgmsg,0,3,0\r\n"},
		{"$$cfgmsg,0,4,0\r\n"},
		{"$$cfgmsg,0,5,0\r\n"},
		{"$$cfgmsg,0,6,0\r\n"},
		{"$$cfgmsg,0,7,0\r\n"},
	};

	printf("sizeof(cfgmsg) = %ld\n", sizeof(cfgmsg));	// 64
	printf("sizeof(cfgmsg)/sizeof(cfgmsg[0]) = %ld\n", sizeof(cfgmsg)/sizeof(cfgmsg[0]));	// 8

	for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
		printf("xy_close_g_all = %s\n", (char *)cfgmsg[i][0]);
	}
}

static void xy_close_g_all_2(void)
{
	int i;
	char * cfgmsg[][1] = {
		{"$$cfgmsg,0,0,0\r\n"},
		{"$$cfgmsg,0,1,0\r\n"},
		{"$$cfgmsg,0,2,0\r\n"},
		{"$$cfgmsg,0,3,0\r\n"},
		{"$$cfgmsg,0,4,0\r\n"},
		{"$$cfgmsg,0,5,0\r\n"},
		{"$$cfgmsg,0,6,0\r\n"},
		{"$$cfgmsg,0,7,0\r\n"},
	};
	char **p;

	printf("sizeof(cfgmsg) = %ld\n", sizeof(cfgmsg));	// 64
	printf("sizeof(cfgmsg)/sizeof(cfgmsg[0]) = %ld\n", sizeof(cfgmsg)/sizeof(cfgmsg[0]));	// 8

	for (i = 0; i < 8; i++) {
		printf("xy_close_g_all_2 = %s\n", (char *)cfgmsg[i][0]);
	}

	p = (char **)cfgmsg;		// 去掉(char **)会告警: warning: assignment from incompatible pointer type [enabled by default]
	printf("p === %s\n", *p);
	printf("p === %s\n", *(p+1));
	
	for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
		printf("repeat ---> xy_close_g_all_2 = %s\n", *(p+i));
	}
}

static void xy_close_g_all_3(void)
{
	int i;
	char * cfgmsg[] = {
		"$$cfgmsg,0,0,0\r\n",
		"$$cfgmsg,0,1,0\r\n",
		"$$cfgmsg,0,2,0\r\n",
		"$$cfgmsg,0,3,0\r\n",
		"$$cfgmsg,0,4,0\r\n",
		"$$cfgmsg,0,5,0\r\n",
		"$$cfgmsg,0,6,0\r\n",
		"$$cfgmsg,0,7,0\r\n",
	};
	char **p;
	char *z;

	printf("sizeof(cfgmsg) = %ld\n", sizeof(cfgmsg));	// 64
	printf("sizeof(cfgmsg)/sizeof(cfgmsg[0]) = %ld\n", sizeof(cfgmsg)/sizeof(cfgmsg[0]));	// 8

	p = cfgmsg;		// 这里不需要(char **)
	for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
		printf("xy_close_g_all_3 = %s\n", *(p+i));
	}

	z = *cfgmsg;
	for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
		printf("repeat ---> xy_close_g_all_3 = %s\n", (z+i));	// 指向第一行,z+i只在第一行移动.
	}

	z = *cfgmsg;
	for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
		printf("repeat2 ---> xy_close_g_all_3 = %s\n", z);	
		z = cfgmsg[i+1];
	}

	z = cfgmsg[0];
	for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
		printf("repeat3 ---> xy_close_g_all_3 = %s\n", z);	
		z = cfgmsg[i+1];
	}

	z = cfgmsg; // 类型不对会告警:warning: assignment from incompatible pointer type [enabled by default]
				// 且首行输出乱码,其它行正常
	for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
		printf("repeat4 ---> xy_close_g_all_3 = %s\n", z);	
		z = cfgmsg[i+1];
	}

}


/*
 * char *p[2]  表示p是一个存储指向char类型数据的指针的数组
 *
 * char (*p)[2]  则表示*p是一个拥有两个char类型元素的数组，那么p则表示指向这个数组的指针
 */
void test()
{
    char *p1[2];
    char (*p2)[2];

    printf("p1----%ld\n", sizeof(p1));	// 16
    printf("p2----%ld\n", sizeof(p2));	// 8

	/* 
	 * 可以看到p1表示的是一个拥有两个(char *)类型的数组，一个指针占有4个字节，俩个当然是8个字节
	 *
	 * 而p2仅仅就只是一个指针，只占有4个字节
	 *
	 * https://www.cnblogs.com/xinglichao/p/9210132.html
	 */
}

/*
 * int (*p)[4]，其实就是吧(*p)和[4]分开来理解，p所指的对象是有4个整形元素的数组，
 * 即p是指向一维数组的指针，或者说p指向的是二维数组的行，然后(*p)[0]指的是p指向的行的第0列。
 */
void f()
{
    int a[2][3] = {{4, 9, 6},{2, 5, 7}};
    int (*p)[3], *q;    //p指 二维数组的行， q指 二维数组的列
    int max = a[0][0];

    for (p = a; p - a < 2 ; p++) {        // p = a意思是p指向a[0]，p - a < 2，意思是有两行，计算时会变成0-0,1-0，不会超过二
        for (q = *p; q - *p < 3 ; q++) {  // *p其实是(*p)[0],即*p指向第0列,这里省略了[0],就像上面p = a，其实是把a[0]赋给p，q - *p < 3意思是三行，意思同上
            if (*q > max)
                max = *q;
        }
    }
    printf("Max: %d\n", max);
}

void main()
{
    char *ch = "init....";
    printf("string = %s, len = %ld\n", ch, sizeof(ch)); // 8
    printf("string = %s, len = %ld\n", ch, strlen(ch)); // 8

    ch = "connected";
    printf("string = %s, len = %ld\n", ch, sizeof(ch)); // 8
    printf("string = %s, len = %ld\n", ch, strlen(ch)); // 9

    ch = "finish...\n";
    printf("string = %s, len = %ld\n", ch, sizeof(ch)); // 8
    printf("string = %s, len = %ld\n", ch, strlen(ch)); // 9

	xy_close_g_all();
	xy_close_g_all_2();
	xy_close_g_all_3();

    f();

	test();
}


#if 0
/**
 * xy_6226_config - Turn on the original observations
 * @none
 */
void xy_6226_config_bak(void)
{
    char * original_observations = "$cfgprt,1,0,115200,3,7\r\n";
    char * cfgmsg[] = {
        "$cfgmsg,2,2,1\r\n",
        "$cfgmsg,2,3,1\r\n",
        "$cfgmsg,2,4,1\r\n",
    };
    char **p;
    int i;

    HAL_Delay(5000);
    ac_traces("configure 6226:\n\n");

    ac_traces(original_observations);
    SEND_6226_CONFIG(original_observations);
    osDelay(200);

    HAL_UART_DeInit(&huart2);
    MX_USART2_Re_Init();
    osDelay(200);

    p = cfgmsg;
    for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
        ac_traces(*(p+i));
        SEND_6226_CONFIG(*(p+i));
        osDelay(200);
    }
}

/**
 * xy_close_g_all - close GGA GLL GSA etc
 * @none
 */
void xy_close_g_all(void)
{
    int i;
    char * cfgmsg[][1] = {
        {"$cfgmsg,0,0,0\r\n"},
        {"$cfgmsg,0,1,0\r\n"},
        {"$cfgmsg,0,2,0\r\n"},
        {"$cfgmsg,0,3,0\r\n"},
        {"$cfgmsg,0,4,0\r\n"},
        {"$cfgmsg,0,5,0\r\n"},
        {"$cfgmsg,0,6,0\r\n"},
        {"$cfgmsg,0,7,0\r\n"},
    };
    char **p;

    ac_traces("close GGA GLL GSA etc:\n");

    p = (char **)cfgmsg;
    for (i = 0; i < sizeof(cfgmsg)/sizeof(cfgmsg[0]); i++) {
        ac_traces(*(p+i));
        SEND_6226_CONFIG(*(p+i));
        osDelay(200);
    }
}
#endif
